#include <Utility/STLVector.hpp>
#include <Utility/STLString.hpp>
#include <UnitTest++.h>
using namespace zzz;

SUITE(STLHelperTest)
{
  TEST(STLVectorTest)
  {
    // constructor
    STLVector<int> x, x1;
    STLVector<int> y(10);
    STLVector<int> z(5,1);
    std::vector<int> wv;
    for (int i=0; i<10; i++) wv.push_back(i);
    STLVector<int> w(wv);
    STLVector<int> v(w);

    // iterator
    x1 = v;
    for (STLVector<int>::iterator vi = w.begin(); vi != w.end(); vi++)
      *vi = -*vi;
    int ii=0;
    for (STLVector<int>::const_iterator vi = w.begin(); vi != w.end(); vi++)
      CHECK_EQUAL(-(ii++), *vi);
    for (STLVector<int>::reverse_iterator vi = w.rbegin(); vi != w.rend(); vi++)
      *vi = -*vi;
    ii=9;
    for (STLVector<int>::const_reverse_iterator vi = w.rbegin(); vi != w.rend(); vi++)
      CHECK_EQUAL(ii--, *vi);

    // capacity
    CHECK_EQUAL(y.max_size(), static_cast<std::vector<int>&>(y).max_size());
    CHECK_EQUAL(y.capacity(), static_cast<std::vector<int>&>(y).capacity());
    CHECK_EQUAL(10, y.size());
    y.resize(5);
    CHECK_EQUAL(5, y.size());
    CHECK(x.empty());
    y.reserve(100);
    CHECK(100 <= y.capacity());

    // element access
    for (int i=0; i<5; i++) CHECK_EQUAL(1, z[i]);
    for (int i=0; i<5; i++) CHECK_EQUAL(1, z.at(i));
    CHECK_EQUAL(0, w.front());
    CHECK_EQUAL(9, w.back());

    // modifiers
    z.assign(10,1);
    for (int i=0; i<10; i++) CHECK_EQUAL(1, z[i]);
    z.assign(w.begin(), w.end());
    for (int i=0; i<10; i++) CHECK_EQUAL(i, z[i]);
    for (int i=0; i<5; i++) x.push_back(i+10);
    for (int i=5; i<10; i++) x.insert(x.end(), i+10);
    for (int i=0; i<10; i++) CHECK_EQUAL(i+10, x[i]);
    for (int i=0; i<5; i++) x.pop_back();
    CHECK_EQUAL(5, x.size());
    x.erase(x.begin(), x.begin()+2);
    CHECK_EQUAL(3, x.size());
    x.clear();
    CHECK(x.empty());
    x.swap(z);
    for (int i=0; i<10; i++) CHECK_EQUAL(i, x[i]);
    CHECK(z.empty());
  }

  TEST(STLStringTest)
  {
    // constructor
    STLString x("hello");
    CHECK_EQUAL("hello", x);
    STLString x1(x);
    CHECK_EQUAL(x1, x);
    STLString z(5,'c');
    CHECK_EQUAL("ccccc", z);
    std::string z1("ccccc");
    CHECK_EQUAL(z1, z);

    // iterator
    STLString rx(x.rbegin(), x.rend());
    CHECK_EQUAL("olleh", rx);

    // capacity
    CHECK_EQUAL(x.max_size(), static_cast<std::string>(x).max_size());
    CHECK_EQUAL(x.capacity(), static_cast<std::string>(x).capacity());
    CHECK_EQUAL(5, x.size());
    CHECK(!x.empty());
    x.reserve(100);
    CHECK(100 <= x.capacity());

    // element access
    for (int i=0; i<5; i++) CHECK_EQUAL(x[i], x1[i]);
    for (int i=0; i<5; i++) CHECK_EQUAL(x[i], x1.at(i));

    // modifiers
    z.assign(10,'x');
    CHECK_EQUAL(std::string("xxxxxxxxxx"), z);
  }
}